MockUI: StatusBar split, tour mode, variable-size menu items, helper texts#17
Merged
k9ert merged 35 commits intok9ert:mainfrom Feb 26, 2026
Merged
Conversation
-Back button size increased -Padding/Gap title to menu contents incrased -Menu layouts harmonized -Realigned header of "manage_wallet_menu"
- language files are stored in folder /i18n and will be detected automatically (if properly named "specter_ui_<language code>.json" -for missing translations the SW falls back to default language -default language = english -all user facing strings are taken from a dictionary with translated strings
-simply a standard menu as other before -made GenericMenu more flexible in order to generate alternative callbacks for menu elements: now also accepts callbacks directly
-Fonts were modified offline and stored in /fonts (lv SYMBOLS were also included) -fonts are now loaded and included in mock_ui.py before instantiating NavigationController
-Made menu size appropriate so no scroll bar appears -merged langaunge texts for "Add Wallet" menu/title -fixed bug in "generate_seedphrase_menu" (corrected call to superclass constructor -Made back button in interface menu same size as rest of UI -Language menu uses BTC ciosn "check" symbol, not lvgl
…" section in main menu No Interface enabled -> no input available to get message to sign -> disable "sign message" option
…aggo83/specter-playground into Mock-UI-Add-framework-for-i18n
findings documented here: k9ert#5
-also added some examples where size (even adaptive to context/state) might make sense
-also grouped "manage storage" and "manage device" into single "manage settings" menu, which is also reachable via dedicated button in the device bar
…groundBranchForIntegration
…osPlaygroundBranchForIntegration
-"Change Wallet" has better fitting symbol (refresh = cycles) -Add Wallet Size is dependent on number of wallets: none -> big, else default size -Moved "Manage Wallet" under "Wallet" section in main menu
removed rounded corners
This reverts commit b15d21e.
After split of status bar into device bar and wallet bar there is more room
- Add UIExplainer component with spotlight overlay effect - Add GuidedTour class as central tour controller - Tour highlights: language, lock, interfaces, battery, power, wallet bar, help icons - Persist tour completion state in ui_state_config.json via UIState - Add TOUR_* translations for English and German - Tour runs automatically on first startup, can be skipped or completed
To better fit the text
-moved files according to recent changes in main -deleted files for which main should be taken over directly
…nchForIntegration
…new menu structure, eliminate hardcoded strings, improve robustness Adapt test case structure for language changes / persistence to new menu structure in GUI Eliminate hardcoded UI strings and language codes from device test infrastructure by loading them from the language JSON files at test collection time. conftest.py: - Add _load_metadata() to read from the "_metadata" section of language JSON files (language_name, language_code, etc.) - Add _supported_lang_codes() to auto-discover available languages by scanning the languages/ directory — ensure_main_menu() now recognises the main menu in any installed language without hardcoding "en"/"de" - Add click_button() helper: asserts label is visible then clicks - Add navigate_to_language_menu(lang): full 3-level navigation (Main → Manage Settings → Manage Device → Select Language) with button labels resolved from JSON for the active language - Add ensure_english(): detects current UI language and switches back to English if needed; called from _require_device so the test suite always starts in a clean known state regardless of previous run outcome - Add --no-build-flash flag to skip build+flash (useful during iteration) - _require_device fixture: builds firmware with ADD_LANG=de, flashes, polls for boot readiness (up to 30s), then calls ensure_english() - pytest.ini: add pythonpath = ../src test_i18n_device.py: - All button labels loaded via _load_label() / _load_metadata() - LANG_EN / LANG_DE constants replace bare "en" / "de" strings - STR_MISSING / STR_UNKNOWN_KEY hardcoded with comment pointing to I18nManager (host import not possible due to micropython dependency in MockUI/__init__.py) - Add gc.collect() before step 4 of test_language_navigation_switch_ persistence to reclaim heap accumulated from repeated find_labels() JSON parsing across the now-deeper (3-level) navigation path All 3 device tests pass (3/3).
…inding on f469 lv.msgbox does not render correctly in the MicroPython LVGL binding on the f469: when parented to None or screen_active(), the widget produces an invisible or mis-sized result that still captures all touch input, effectively freezing the UI. The fix replaces lv.msgbox with a manually constructed ModalOverlay class (basic/modal_overlay.py) that creates a full-screen lv.obj directly on layer_top — the only layer LVGL composites unconditionally above all screen content. UIExplainer (guided tour) is refactored to use the same ModalOverlay, removing its own duplicated layer_top setup code. Both consumers now close the modal via modal.close().
cee0ad5 to
ad95be1
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR brings several UI improvements to MockUI and a small refactor of
the device test infrastructure.
UI Changes
StatusBar → DeviceBar + WalletBar
The monolithic
status_bar.pyhas been replaced by two focused components:device_bar.py— shows device state (lock status, battery, etc.)wallet_bar.py— shows active wallet contextTour Mode
New
tour/package with a guided first-run experience:ui_explainer.py— overlay component for contextual help textguided_tour.py— orchestrates the step-by-step tour flowVariable-size Menu Items
menu.pyandmain_menu.pyupdated to support menu entries of differentheights, enabling richer layouts with subtitles or icons.
Settings Menu
New
settings_menu.pyadded to the device submenu hierarchy.Helper Texts & i18n
specter_ui_en.jsonandspecter_ui_de.jsonUI State Helper
New
helpers/ui_state.pycentralises shared UI state logic (to replaced with actual business logic of specter hw later on).Device Test Infrastructure
Refactor of
tests_device/— all hardcoded UI strings replaced withvalues loaded from the language JSON files at collection time:
_load_label(key, *langs)— reads fromtranslationssection_load_metadata(key, *langs)— reads from_metadatasection(used for
language_name)_supported_lang_codes()— auto-discovers languages by scanningthe
languages/directory;ensure_main_menu()now works for anyinstalled language without hardcoding codes
click_button(label)— asserts visibility then clicksnavigate_to_language_menu(lang)— full 3-level navigation withlabels resolved for the active language
ensure_english()— detects current UI language and switches backto English if needed; called from
_require_deviceso every runstarts in a clean known state
LANG_EN/LANG_DEconstants replace bare"en"/"de"strings--no-build-flashflag to skip build+flash during iterationgc.collect()before the final navigation step to reclaim heapaccumulated from repeated JSON parsing over serial
All 3 device integration tests pass (3/3).
All 100 unit tests continue to pass.